package com.yg.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yg.config.FilePathConfig;
import com.yg.config.exceptionhandler.NoTeacherException;
import com.yg.config.exceptionhandler.YGException;
import com.yg.config.result.R;
import com.yg.config.result.ResultCode;
import com.yg.entity.readAndWriteTemplates.TeacherPracticeRead;
import com.yg.entity.singleEntity.Teacher;
import com.yg.entity.singleEntity.TeacherPractice;
import com.yg.mapper.TeacherEducationMapper;
import com.yg.mapper.TeacherMapper;
import com.yg.mapper.TeacherPracticeMapper;
import com.yg.service.TeacherPracticeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * <p>
 * 对应sheet04，此表是教师实践锻炼表
注意！此表的id和教师表的id是一个id 服务实现类
 * </p>
 *
 * @author YingGu
 * @since 2020-11-04
 */
@Service
public class TeacherPracticeServiceImpl extends ServiceImpl<TeacherPracticeMapper, TeacherPractice> implements TeacherPracticeService {

    @Autowired
    TeacherPracticeMapper teacherPracticeMapper;
    @Autowired
    TeacherEducationMapper teacherEducationMapper;
    @Autowired
    TeacherMapper teacherMapper;
    @Autowired
    FilePathConfig filePathConfig;

    /**
     * 查询
     * @return
     */
    @Override
    public R selectAllTeacherPracticeInfo(int current,int limit,String vipByJwtToken,String teacherIdByJwtToken) {
        //Page类的构造函数中第一个参数为当前查询第几页，第二个参数为每页的记录数(分页查询)
        Page<TeacherPracticeRead> teacherPracticeReadPage = new Page<TeacherPracticeRead>(current,limit);
        IPage<TeacherPracticeRead> teacherPracticeReadIPage = teacherPracticeMapper.selectAllTeacherPracticeInfo(teacherPracticeReadPage,vipByJwtToken,teacherIdByJwtToken);
        List<TeacherPracticeRead> records = teacherPracticeReadIPage.getRecords();

        return R.OK().data("list",records).data("total",teacherPracticeReadIPage.getTotal()).data("pages",teacherPracticeReadIPage.getPages());
    }

    /**
     * 录入excel
     * @param fileInputStream
     * @return
     */
    @Transactional
    @Override
    public R readExcel(FileInputStream fileInputStream) {
        //创建要录入的bean的list
        List<TeacherPractice> teacherPracticeList = new ArrayList<TeacherPractice>();
        //创建R
        R r = R.getR();
        r.setCode(ResultCode.SUCCESS);
        //存储错误信息
        List<String> errorList = new ArrayList<>();

        //读取excel(匿名内部类解决传参问题)
        EasyExcel.read(fileInputStream, TeacherPracticeRead.class, new AnalysisEventListener<TeacherPracticeRead>() {

            //每行执行
            @Override
            public void invoke(TeacherPracticeRead teacherPracticeRead, AnalysisContext analysisContext) {
                //创建数据库对应实体类
                if (teacherPracticeRead.getPracticeUnit() != null){ //判断是否读到注解
                    Teacher teacher = new Teacher();
                    TeacherPractice teacherPractice = new TeacherPractice();

                    BeanUtils.copyProperties(teacherPracticeRead,teacherPractice);

                    //添加进list
                    teacherPracticeList.add(teacherPractice);
                }

            }

            //所有行读完执行
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

                if (r.getCode() == ResultCode.SUCCESS){
                    //向数据库插入数据
                    saveData();
                }else {
                    //添加错误信息
                    r.data("errorMsg",errorList);
                }
            }


            /**
             * 数据类型转换异常处理
             * @param exception
             * @param context
             * @throws Exception
             */
            @Override
            public void onException(Exception exception, AnalysisContext context) throws Exception {
                if (exception instanceof ExcelDataConvertException) {
                    ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;

                    //向errorList中添加信息
                    r.code(ResultCode.ERROR);
                    System.out.println("行："+excelDataConvertException.getRowIndex() + "列" +excelDataConvertException.getColumnIndex());
                    errorList.add("行："+excelDataConvertException.getRowIndex() + "列" +excelDataConvertException.getColumnIndex());
//                    LOGGER.error("第{}行，第{}列解析异常", excelDataConvertException.getRowIndex(),
//                            excelDataConvertException.getColumnIndex());
                }
            }

            //存数据库操作
            private void saveData(){
                for (int i = 0; i < teacherPracticeList.size(); i++) {
                    QueryWrapper<Teacher> teacherPracticeQueryWrapper = new QueryWrapper<>();
                    teacherPracticeQueryWrapper.eq("teacher_id",teacherPracticeList.get(i).getId());
                    Teacher teacher = teacherMapper.selectOne(teacherPracticeQueryWrapper);
                    if (teacher != null){
                        try {
                            teacherPracticeMapper.insert(teacherPracticeList.get(i));
                        } catch (RuntimeException e) {
                            throw new YGException(ResultCode.INSERTERROR,e.getCause().getMessage(),i + 5);
                        }
                        System.out.println("插入成功");
                    }else {
                        throw new NoTeacherException(ResultCode.USERDOESNOTEXIST,"没有找到" + teacherPracticeList.get(i).getId() + "教职工号");
                    }
                }

                //r中写入成功信息
                r.code(ResultCode.SUCCESS).message("插入成功");
            }
        }).headRowNumber(4).sheet().doRead();

        return r;
    }


    /**
     * 导出表格
     * @param response
     * @param condition
     * @return
     */
    @Transactional
    @Override
    public R writeExcel(HttpServletResponse response,TeacherPracticeRead condition) {
        //从数据库中查询对应表格
        List<TeacherPracticeRead> teacherPracticeReadList = teacherPracticeMapper.WriteTeacherPracticeConditionalQuery(condition);

        //将数据库对应的bean复制给导出表格bean
        for (int i = 0; i < teacherPracticeReadList.size(); i++) { //复制teacher中的属性
            //设置序号
            teacherPracticeReadList.get(i).setNum(i + 1);
            teacherPracticeReadList.get(i).setAge(Calendar.getInstance().get(Calendar.YEAR) - Integer.valueOf(teacherPracticeReadList.get(i).getBirthday().substring(0,4)));
        }

        //导出(匿名内部类SheetWriteHandler)
        response.addHeader("Content-Disposition", "attachment;fileName=下载案例4.xlsx");// 设置文件名
        try {
            EasyExcel.write(response.getOutputStream()).withTemplate(filePathConfig.writeExcelFilePath + "sheet04Template.xlsx").registerWriteHandler(new SheetWriteHandler() {

                @Override
                public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

                }

                @Override
                public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
                    //日志
                }


            }).sheet().doFill(teacherPracticeReadList);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return R.OK();
    }

    /**
     * 条件查询
     * @param s
     * @return
     */
    @Transactional
    @Override
    public R teacherConditionalQuery(String vipByJwtToken ,String s,int current ,int limit) {
        Page<TeacherPracticeRead> teacherPracticeReadPage = new Page<TeacherPracticeRead>(current,limit);
        TeacherPracticeRead teacherPracticeRead = JSONObject.parseObject(s, TeacherPracticeRead.class);
        IPage<TeacherPracticeRead> teacherPracticeReadIPage = teacherPracticeMapper.teacherPracticeConditionalQuery(teacherPracticeReadPage, teacherPracticeRead,vipByJwtToken);
        List<TeacherPracticeRead> records = teacherPracticeReadIPage.getRecords();
        return records.size() != 0 ? R.OK().data("list",records).data("total",teacherPracticeReadIPage.getTotal()).data("pages",teacherPracticeReadIPage.getPages()) : R.OK().message("您所查询的信息不存在").data("teacherConditionalList",records);
    }

    /**
     * 更新
     * @param teacherJson
     * @return
     */
    @Override
    public R updateTeacherInfo(String teacherJson) {
        //Json转换
        TeacherPracticeRead teacherPracticeRead = JSONObject.parseObject(teacherJson, TeacherPracticeRead.class);
        TeacherPractice teacherPractice = new TeacherPractice();
        //复制属性
        BeanUtils.copyProperties(teacherPracticeRead,teacherPractice);

        //构造条件
        QueryWrapper<TeacherPractice> teacherPracticeQueryWrapper = new QueryWrapper<TeacherPractice>();
        teacherPracticeQueryWrapper.eq("id",teacherPracticeRead.getId());

        //返回数值1
        int update = teacherPracticeMapper.update(teacherPractice, teacherPracticeQueryWrapper);

        return update == 1 ? R.OK().message(teacherPracticeRead.getId() + "修改成功") : R.ERROR().code(ResultCode.UPDATEERROR).message(teacherPractice.getId() + "修改失败");
    }

    /**
     * 根据teahcerId删除教师
     * @param id
     * @return
     */
    @Override
    public R deleteTeacherById(String id) {
        int id1 = teacherPracticeMapper.delete(new QueryWrapper<TeacherPractice>().eq("id", id));
        return id1 == 1 ? R.OK().message("删除成功") : R.ERROR().code(ResultCode.DELETEERROR).message("删除失败");
    }

    /**
     * 插入教师实践信息
     * @param teacherPractice
     * @return
     */
    @Override
    public R insertTeacherPractice(TeacherPractice teacherPractice) {
        Teacher teacher_id = teacherMapper.selectOne(new QueryWrapper<Teacher>().eq("teacher_id", teacherPractice.getId()));
        int insert = 0;
        if (teacher_id != null){
            try {
                insert = teacherPracticeMapper.insert(teacherPractice);
            } catch (RuntimeException e) {
                throw new YGException(ResultCode.INSERTERROR,e.getCause().getMessage(),1);
            }
        }
        return insert == 1 ? R.OK().message("插入成功") : R.ERROR().code(ResultCode.INSERTERROR).message(teacherPractice.getId() + "没有找到该教师");
    }

}
